package com.habook.ui;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Enumeration;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;

import com.habook.image.ImageHelper;
import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;

public class HaFrame extends JFrame {

	private static final long serialVersionUID = -5505102492720739208L;

	public static final String VERSION = "1.0";
	public static final String TITLE = String.format("Java Handy Book v%s", VERSION);
	public static final String INTRODUCTION = "Notepad Memo, Address Book, Alarm Clock";
	public static final String WEBSITE = "http://code.google.com/p/habook/";

	private static void setLookAndFeel(String lnfName) {
		try {
			UIManager.setLookAndFeel(lnfName);
		} catch (Exception exc) {
			System.err.println("Could not load LookAndFeel: " + lnfName);
		}
	}

	private static void initGlobalFontSetting(Font fnt) {
		FontUIResource fontRes = new FontUIResource(fnt);
		for (Enumeration<Object> keys = UIManager.getDefaults().keys(); keys.hasMoreElements();) {
			Object key = keys.nextElement();
			Object value = UIManager.get(key);
			if (value instanceof FontUIResource)
				UIManager.put(key, fontRes);
		}
	}

	private static boolean setSystemTray(final JFrame frame) {
		final TrayIcon trayIcon;

		if (SystemTray.isSupported()) {
			PopupMenu popup = new PopupMenu();
			MenuItem exit = new MenuItem("Exit");
			exit.setFont(new Font("Dialog", Font.BOLD, 12));
			exit.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					System.exit(0);
				}
			});
			popup.add(exit);

			trayIcon = new TrayIcon(ImageHelper.ICON_LOGO.getImage(), TITLE, popup);
			trayIcon.setImageAutoSize(true);
			trayIcon.addMouseListener(new TrayMouseListener() {
				@Override
				public void mouseClicked(MouseEvent e) {
					// MouseEvent.BUTTON1 代表左键，
					// MouseEvent.BUTTON3 代表右键，
					// MouseEvent.BUTTON2 代表中间的键，如果你的鼠标有三个键的话。
					if (e.getButton() != MouseEvent.BUTTON3) {
						// BUTTON3 已用于弹出菜单
						frame.setVisible(true);
						frame.requestFocus();
						frame.requestFocusInWindow();
						frame.toFront();
						frame.setState(JFrame.NORMAL);
					}
				}
			});

			try {
				SystemTray.getSystemTray().add(trayIcon);
				frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
				frame.addWindowListener(new TrayWindowListener() {
					@Override
					public void windowIconified(WindowEvent e) {
						frame.setVisible(false);
					}

					@Override
					public void windowClosing(WindowEvent e) {
						int option = JOptionPane.showConfirmDialog(frame, //
								"Are you sure you want to exit?", "Confirm", //
								JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
						if (option == JOptionPane.YES_OPTION)
							System.exit(0);
					}
				});
				trayIcon.displayMessage(TITLE, String.format("%s\n%s", WEBSITE, INTRODUCTION), //
						TrayIcon.MessageType.INFO);
				return true;
			} catch (AWTException e) {
				return false;
			}
		} else { // System Tray is not supported
			return false;
		}
	}

	private static void setSystemHotkey(final JFrame frame) {
		if (!JIntellitype.isJIntellitypeSupported()) {
			System.err.println("JIntellitype.DLL is not found in the path or this is not Windows 32bit OS.");
		} else {
			final int fhide = 1;
			final int fexit = 2;
			JIntellitype.getInstance().registerHotKey(fhide, JIntellitype.MOD_CONTROL, KeyEvent.VK_Q);
			JIntellitype.getInstance().registerHotKey(fexit, JIntellitype.MOD_CONTROL + JIntellitype.MOD_SHIFT, KeyEvent.VK_Q);
			JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
				@Override
				public void onHotKey(int key) {
					if (key == fhide) {
						frame.setVisible(!frame.isVisible() || !frame.isFocused());
						if (frame.isVisible()) {
							frame.requestFocus();
							frame.requestFocusInWindow();
							frame.toFront();
							frame.setState(JFrame.NORMAL);
						}
					} else if (key == fexit) {
						System.exit(0);
					}
				}
			});
			Runtime.getRuntime().addShutdownHook(new Thread() {
				public void run() {
					JIntellitype.getInstance().unregisterHotKey(fhide);
					JIntellitype.getInstance().unregisterHotKey(fexit);
					JIntellitype.getInstance().cleanUp();
				}
			});
		}
	}

	public static JFrame Main(String[] args) {
		setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
		initGlobalFontSetting(new Font("Dialog", Font.PLAIN, 12));
		HaFrame hf = new HaFrame();
		hf.setSize(600, 450);
		hf.setLocationRelativeTo(null);
		hf.setResizable(false);
		hf.setTitle(TITLE);
		hf.setLayout(new BorderLayout());
		hf.add(new HaPanel(), BorderLayout.CENTER);
		hf.setIconImage(ImageHelper.ICON_LOGO.getImage());
		if (!setSystemTray(hf)) {
			hf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			hf.setVisible(true);
		}
		setSystemHotkey(hf);
		return hf;
	}

	public static void main(String[] args) {
		Main(args);
	}
}

class HaPanel extends JPanel {

	private static final long serialVersionUID = -6527373651270034792L;

	public HaPanel() {
		try {
			SwingUtilities.invokeAndWait(new Runnable() {
				public void run() {
					makeGUI();
				}
			});
		} catch (Exception exc) {
			System.err.println("Can't create because of " + exc);
		}
	}

	private void makeGUI() {
		JTabbedPane jtp = new JTabbedPane();
		jtp.addTab("Handy Notes", ImageHelper.ICON_NOTEPAD, new HandyNotesPanel());
		jtp.setMnemonicAt(0, 'N');
		jtp.setDisplayedMnemonicIndexAt(0, 6);
		jtp.addTab("Address Book", ImageHelper.ICON_ADDRESS_BOOK, new AddressBookPanel());
		jtp.setMnemonicAt(1, 'B');
		jtp.addTab("Alarm Clock", ImageHelper.ICON_ALARM_CLOCK, new AlarmClockPanel());
		jtp.setMnemonicAt(2, 'C');
		setLayout(new BorderLayout());
		add(jtp, BorderLayout.CENTER);
	}
}

abstract class TrayMouseListener implements MouseListener {
	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}
}

abstract class TrayWindowListener implements WindowListener {
	@Override
	public void windowActivated(WindowEvent e) {
	}

	@Override
	public void windowClosed(WindowEvent e) {
	}

	@Override
	public void windowClosing(WindowEvent e) {
	}

	@Override
	public void windowDeactivated(WindowEvent e) {
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
	}

	@Override
	public void windowIconified(WindowEvent e) {
	}

	@Override
	public void windowOpened(WindowEvent e) {
	}
}
